/*
 * @(#)FileReader.java
 *
 * Copyright 2007 youlq . All rights reserved.
 * youlq PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package jude.java.util;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * todo description <p/> History: create 2007-9-3 16:06:05
 * 
 * @author ������ (youlq)
 * @version 0.1 2007-9-3 16:06:05
 */
public class FileHelper {
	public static final Log LOG = LogFactory.getLog(FileHelper.class);

	private static MessageDigest getDigest() {
		try {
			return MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}

	public static String getMD5(String fileName) throws FileNotFoundException {
		return getMD5(null, fileName);
	}

	public static String getMD5(String path, String fileName)
			throws FileNotFoundException {
		File f;
		if (null != path) {
			if (!path.endsWith("/")) {
				path = path + "/";
			}
			f = new File(path + fileName);
		} else {
			f = new File(fileName);
		}
		InputStream is = new FileInputStream(f);
		byte[] buffer = new byte[8192];
		int read = 0;
		try {
			MessageDigest digest = getDigest();
			while ((read = is.read(buffer)) > 0) {
				digest.update(buffer, 0, read);
			}
			byte[] md5sum = digest.digest();
			BigInteger bigInt = new BigInteger(1, md5sum);
			return bigInt.toString(16);
		} catch (IOException e) {
			LOG.error("exception :" + e.getMessage(), e);
			return "";
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				LOG.error("exception :" + e.getMessage(), e);
			}
		}
	}
	
	public static int transfer(InputStream in, OutputStream out) throws IOException {
		int n = 0;
		byte[] buffer = new byte[4096];
		int c;
		while((c = in.read(buffer)) >= 0) {
			out.write(buffer, 0, c);
			n += c;
		}
		return n;
	}
	
	/**
	 * @param is ��δ�ر�
	 * */
	public static byte[] getByteFromStream(InputStream is, int size) throws IOException {
		if (size < 0) {
			throw new IOException("invalid size: " + size);
		}
		byte[] bytes = new byte[size];
		int pos = 0;
		int n = 0;
		while (pos < size && (n = is.read(bytes, pos, size - pos)) >= 0) {
			pos += n;
		}
		if (pos < size) {
			throw new IOException("Could not completely read stream: " + size);
		}
		return bytes;
	}

	public static byte[] getBytesFromFile(File file) throws IOException {
		long length = file.length();
		if (length > Integer.MAX_VALUE) {
			throw new IOException("File is too large");
		}
		InputStream is = new FileInputStream(file);
		try {
			return getByteFromStream(is, (int)length);
		}finally {
			is.close();
		}
	}

	/**
	 * ��ʽ���ļ��� grwh{yyyyMMdd}.txt ȥ���ļ���ǰ���·���� /ll/rmbll.txt -> rmbll.txt
	 * 
	 * @param filenamein
	 * @return
	 */
	public static String parseFilename(String filenamein,
			boolean isReturnFilePath) {
		String filenameout = filenamein;
		String regxStr = "\\{\\w*\\}";
		Pattern pattern = Pattern.compile(regxStr);
		Matcher matcher = pattern.matcher(filenamein);
		if (matcher.find()) {
			String match = matcher.group();
			match = StringUtils.mid(match, 1, match.length() - 2);
			String s = new SimpleDateFormat(match).format(new Date());
			filenameout = filenamein.replaceAll(regxStr, s);
		}
		if (isReturnFilePath) {
			return filenameout;
		} else {
			return StringUtils.contains(filenameout, "/") ? StringUtils
					.substringAfterLast(filenameout, "/") : filenameout;
		}

	}

	/**
	 * ��ʽ���ļ��� grwh{yyyyMMdd}.txt ȥ���ļ���ǰ���·���� /ll/rmbll.txt -> rmbll.txt
	 * 
	 * @param filenamein *
	 * @param date
	 * @return
	 */
	public static String parseFilename(String filenamein, Date date) {
		String filenameout = filenamein;
		String regxStr = "\\{\\w*\\}";
		Pattern pattern = Pattern.compile(regxStr);
		Matcher matcher = pattern.matcher(filenamein);
		if (matcher.find()) {
			String match = matcher.group();
			match = StringUtils.mid(match, 1, match.length() - 2);
			String s = new SimpleDateFormat(match).format(date);
			filenameout = filenamein.replaceAll(regxStr, s);
		}

		return StringUtils.contains(filenameout, "/") ? StringUtils
				.substringAfterLast(filenameout, "/") : filenameout;
	}

	public static boolean createPath(String domainEtlPath) {
		if (!(new File(domainEtlPath)).exists()) {
			LOG.info(domainEtlPath + " is not exists! Now we create it.");
			boolean success = (new File(domainEtlPath)).mkdirs();
			if (!success) {
				LOG.error("can not create path:" + domainEtlPath);
			}
			return success;
		}
		return true;
	}

	/**
	 * ���Ƶ����ļ�
	 * 
	 * @param originFilePath
	 *            String ԭ�ļ�·��
	 * @param targetFilePath
	 *            String ���ƺ�·��
	 * @throws �����ļ���С,
	 *             -1��ʾδ����
	 */
	public static int copyFile(String originFilePath, String targetFilePath,
			boolean overWrite) throws IOException {
		int bytesum = -1;
		int byteread = 0;
		File targetFile = new File(targetFilePath);
		if (!overWrite && targetFile.exists()) {
			throw new IOException("file " + targetFilePath
					+ " exists! not allow to overwrite");
		}
		File originFile = new File(originFilePath);
		// if (originFile.exists()) {
		InputStream in = new FileInputStream(originFile);
		FileOutputStream out = new FileOutputStream(targetFile);
		byte[] buffer = new byte[2048];
		while ((byteread = in.read(buffer)) != -1) {
			bytesum += byteread;
			out.write(buffer, 0, byteread);
		}
		in.close();
		out.close();
		// }
		return bytesum;
	}

	/**
	 * �ж��Ƿ�Ϸ��ļ���
	 * 
	 * @param filename
	 * @return
	 */
	public static boolean isLegalFilename(String filename) {
		Pattern pattern = Pattern.compile("^[^\\/\\\\<>\\*\\?\\:\"\\|]+$");
		Matcher matcher = pattern.matcher(filename);
		return matcher.find(); // true
	}

	/**
	 * ȡ���¸�����
	 * 
	 * @param day
	 * @return
	 */
	public static Date getNextDate(int day) {
		Date date = new Date();
		java.util.Calendar c = java.util.Calendar.getInstance();
		c.setTime(date);
		c
				.setTimeInMillis(c.getTimeInMillis() - ((long) day) * 24 * 3600
						* 1000);
		return c.getTime();
	}

	
	/**
	 * ɾ���ļ���
	 * @param folderPath
	 */
	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath);
			String filePath = folderPath;
			filePath = filePath.toString();
			File myFilePath = new File(filePath);
			myFilePath.delete();
		} catch (Exception e) {
			LOG.error(e);
		}
	}

	// delete file
	// param path
	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);
				delFolder(path + "/" + tempList[i]);
				flag = true;
			}
		}
		return flag;
	}
}
